'''
Created on 22/07/2012

@author: Elfi
'''

try:
    from couchbase import Couchbase
except ImportError:
    print "Warning!!! Couchbase is not installed or wrong version"

from metrics.singletonmixin import Singleton

def convert_to_builtin_type(obj):
    # Convert objects to a dictionary of their representation
    d = { '__class__':obj.__class__.__name__, 
          '__module__':obj.__module__,
          }
    d.update(obj.__dict__)
    return d


class DBConnection(Singleton):
    '''
    classdocs
    '''

    __cbclient = 0
    __obj__cache = []
    __expire_time = 60*60*24 # 1 day

    def __init__(self):
        '''
        Constructor
        '''
        super(DBConnection,self).__init__()
        
    def initialize(self, host = "localhost", port = "8091", password = "", bucket = "default"):
        self.__cbclient = Couchbase.connect( host=host, port = port, bucket=bucket, password=password )
        self.__bucket = bucket
        
    def __del__(self):
        ''' Nothing to do so far '''   
        self.flushCache()
    
    def flushCache(self):
        if not self.isConnected:
            return
        
        import sys, traceback
        for o in self.__obj__cache:
            try:
                o.storeObject(self)
            except:
                print "Couldn't store object: ", sys.exc_info()
                traceback.print_exc(file=sys.stdout)

        self.__obj__cache = []
    
    def storeObject(self, obj):
        '''
        Store the object using a common process
        '''
        
        if not self.isConnected:
            raise RuntimeWarning( "DB Connection has not been initialized" )

        '''Create the id'''
        doc_id = obj.docid()
        d = convert_to_builtin_type(obj)
        
        '''Store the document'''
        self.__cbclient.set(doc_id, d, ttl=self.__expire_time )
        
    @property
    def expireTime(self):
        return self.__expire_time
    
    @expireTime.setter
    def expireTime(self, value):
        self.__expire_time = value
        
    @property
    def isConnected(self):
        return self.__cbclient != 0
        
    def cacheObject(self, obj):
        '''Cache the object until flushCache is called or this instance is terminated'''
        self.__obj__cache.append(obj)
        
    def urlDependencies(self, url):
        import json
        
        if not self.isConnected:
            raise RuntimeWarning( "DB Connection has not been initialized" )
        
        '''Get the list of URL which are inner calls to the URL sent by parameter'''
        '''Just one result will be available per URL'''
        v = self.__cbclient._view("dev_site_dep","inner_urls", {'key': json.dumps(url), 'limit': '1' })
        
        return v.value["rows"][0]["value"]
    
    def siteContents(self, url):
        import json

        if not self.isConnected:
            raise RuntimeWarning( "DB Connection has not been initialized" )

        '''Get the content for the url'''
        v = self.__cbclient._view("dev_site_dep","site_content", {'key': json.dumps(url)})
        
        return v.value["rows"]
